<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html lang="en">
<head>
	<meta http-equiv="Content-Type" content="text/html;charset=UTF-8">
	<title>进阶：10、过渡状态 动态状态转换</title>
	<script type="text/javascript" src="https://unpkg.com/vue/dist/vue.js"></script>
	<script src="https://cdnjs.cloudflare.com/ajax/libs/gsap/1.18.5/TweenLite.min.js"></script>	
	<style type="text/css">
	svg { display: block; }
	polygon { fill: #41B883; }
	circle {
	  fill: transparent;
	  stroke: #35495E;
	}
	input[type="range"] {
	  display: block;
	  width: 100%;
	  margin-bottom: 15px;
	}	
	</style>
</head>
<body>
	<div id="app">
	  <svg width="200" height="200">
	    <polygon :points="points"></polygon>
	    <circle cx="100" cy="100" r="90"></circle>
	  </svg>
	  <label>Sides: {{ sides }}</label>
	  <input 
	    type="range" 
	    min="3" 
	    max="500" 
	    v-model.number="sides"
	  >
	  <label>Minimum Radius: {{ minRadius }}%</label>
	  <input 
	    type="range" 
	    min="0" 
	    max="90" 
	    v-model.number="minRadius"
	  >
	  <label>Update Interval: {{ updateInterval }} milliseconds</label>
	  <input 
	    type="range" 
	    min="10" 
	    max="2000"
	    v-model.number="updateInterval"
	  >
	</div>	

	<script type="text/javascript">
		// 代码挺负责，但逻辑简单
		// 主要就是通过三个数据绑定的表单对数据进行动态更新
		// 数据一变化其监视者会根据变化前后的值执行响应的回调
		// 结合插件从而渲染出酷炫的效果
		new Vue({
		  el: '#app',
		  data: function () {
		  	var defaultSides = 10
		  	var stats = Array.apply(null, { length: defaultSides })
		    	.map(function () { return 100 })
		  	return {
		    	stats: stats,
		    	points: generatePoints(stats),
		      sides: defaultSides,
		      minRadius: 50,
		      interval: null,
		      updateInterval: 500
		    }
		  },
		  watch: {
		  	sides: function (newSides, oldSides) {
		    	var sidesDifference = newSides - oldSides
				if (sidesDifference > 0) {
					for (var i = 1; i <= sidesDifference; i++) {
						this.stats.push(this.newRandomValue())
					}
				} else {
				var absoluteSidesDifference = Math.abs(sidesDifference)
					for (var i = 1; i <= absoluteSidesDifference; i++) {
						this.stats.shift()
					}
				}
		    },
		    stats: function (newStats) {
				TweenLite.to(
			      	this.$data, 
			        this.updateInterval / 1000, 
			        { points: generatePoints(newStats) }
		    	)
		    },
		    updateInterval: function () {
		    	this.resetInterval()
		    }
		  },
		  mounted: function () {
		  	this.resetInterval()
		  },
		  methods: {
		    randomizeStats: function () {
		    	var vm = this
		    	this.stats = this.stats.map(function () {
		      	return vm.newRandomValue()
		      })
		    },
		    newRandomValue: function () {
		    	return Math.ceil(this.minRadius + Math.random() * (100 - this.minRadius))
		    },
		    resetInterval: function () {
		    	var vm = this
		    	clearInterval(this.interval)
		      this.randomizeStats()
		    	this.interval = setInterval(function () { 
		      	vm.randomizeStats()
		      }, this.updateInterval)
		    }
		  }
		})

		function valueToPoint (value, index, total) {
		  var x     = 0
		  var y     = -value * 0.9
		  var angle = Math.PI * 2 / total * index
		  var cos   = Math.cos(angle)
		  var sin   = Math.sin(angle)
		  var tx    = x * cos - y * sin + 100
		  var ty    = x * sin + y * cos + 100
		  return { x: tx, y: ty }
		}

		function generatePoints (stats) {
			var total = stats.length
			return stats.map(function (stat, index) {
		    var point = valueToPoint(stat, index, total)
		    return point.x + ',' + point.y
		  }).join(' ')
		}		
	</script>
</body>
</html>